---
title: Grouped Steps Workflow
description: Organize multiple steps into reusable, logical sequences for complex workflows with clean separation of concerns
---

**Key Benefits**: Reusable sequences, cleaner branching logic, modular workflow design

Grouped steps enable modular workflow architecture with reusable components and clear logical boundaries.

## Basic Example

```python grouped_steps_workflow.py
from agno.workflow import Steps, Step, Workflow

# Create a reusable content creation sequence
article_creation_sequence = Steps(
    name="ArticleCreation",
    description="Complete article creation workflow from research to final edit",
    steps=[
        Step(name="research", agent=researcher),
        Step(name="writing", agent=writer),
        Step(name="editing", agent=editor),
    ],
)

# Use the sequence in a workflow
workflow = Workflow(
    name="Article Creation Workflow",
    steps=[article_creation_sequence]  # Single sequence
)

workflow.print_response("Write an article about renewable energy", markdown=True)
```

## Steps with Router

This is where `Steps` really shines - creating distinct sequences for different content types or workflows:

```python
from agno.workflow import Steps, Router, Step, Workflow

# Define two completely different workflows as Steps
image_sequence = Steps(
    name="image_generation",
    description="Complete image generation and analysis workflow",
    steps=[
        Step(name="generate_image", agent=image_generator),
        Step(name="describe_image", agent=image_describer),
    ],
)

video_sequence = Steps(
    name="video_generation",
    description="Complete video production and analysis workflow",
    steps=[
        Step(name="generate_video", agent=video_generator),
        Step(name="describe_video", agent=video_describer),
    ],
)

def media_sequence_selector(step_input) -> List[Step]:
    """Route to appropriate media generation pipeline"""
    if not step_input.input:
        return [image_sequence]

    message_lower = step_input.input.lower()

    if "video" in message_lower:
        return [video_sequence]
    elif "image" in message_lower:
        return [image_sequence]
    else:
        return [image_sequence]  # Default

# Clean workflow with clear branching
media_workflow = Workflow(
    name="AI Media Generation Workflow",
    description="Generate and analyze images or videos using AI agents",
    steps=[
        Router(
            name="Media Type Router",
            description="Routes to appropriate media generation pipeline",
            selector=media_sequence_selector,
            choices=[image_sequence, video_sequence],  # Clear choices
        )
    ],
)

# Usage examples
media_workflow.print_response("Create an image of a magical forest", markdown=True)
media_workflow.print_response("Create a cinematic video of city timelapse", markdown=True)
```

## Developer Resources

- [`workflow_using_steps.py`](/examples/concepts/workflows/01-basic-workflows/workflow_using_steps)
- [`workflow_using_steps_nested.py`](/examples/concepts/workflows/01-basic-workflows/workflow_using_steps_nested)
- [`selector_for_image_video_generation_pipelines.py`](/examples/concepts/workflows/05_workflows_conditional_branching/selector_for_image_video_generation_pipelines)

## Reference

For complete API documentation, see [Steps Reference](/reference/workflows/steps-step).